package mapper;

import com.tomorrow.javabean.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.ArrayList;
import java.util.List;

@Mapper
public interface UserAnnotationMapper {
    //注解开发
    /*
    @Select 注解 省略创建.xml文件，dao接口中直接在方法上写sql语句  (注意：@Delete, @Update, @Insert的注解用法都相同)
        @Select(value = "") / @Select("") 两种使用形式均可，一般使用第二种简写方式
        @Select("select * from user") 可以注解书写sql字符串，表示当前注解接口被调用会自动执行该sql语句
        @Select("<script>" + ...... + "</script>") 可以将写在.xml映射文件中的动态sql语句写入中间进行识别执行，
            注意：在使用动态sql时内容必须用 script 标签进行包裹
    */
    @Select("<script> \n" +
            "select * \n" +
            "        from user \n" +
            "        <where> \n" +
            "            <if test=\"username != null and username != '' \">\n" +
            "                username = #{username}\n" +
            "            </if>\n" +
            "            <if test=\"phone != null and phone != '' \">\n" +
            "                or phone = #{phone}\n" +
            "            </if>\n" +
            "        </where>" +
            "</script>")
    @ResultMap("userMapResult1")
    public List<User> findUserByNameOrPhoneAnnotation(User user);

    @Insert("insert into user(username, password, phone) values (#{username}, #{password}, #{phone})")
    public int addUser(User user);

    @Update("<script>" +
            "update user\n" +
            "<set>\n" +
            "    <if test=\"username != null and username != '' \">\n" +
            "        username=#{username},\n" +
            "    </if>\n" +
            "    <if test=\"password != null and password != '' \">\n" +
            "        `password`=#{password},\n" +
            "    </if>\n" +
            "    <if test=\"phone != null and phone != '' \">\n" +
            "        phone=#{password},\n" +
            "    </if>\n" +
            "</set>\n" +
            "<where>\n" +
            "    <if test=\"uid != null and uid != '' \">\n" +
            "        or uid = #{uid}\n" +
            "    </if>\n" +
            "</where>" +
            "</script>")
    public int updateUser(User user);

    @Delete("delete from user where uid=#{uid}")
    public int deleteUserById(Integer id);

    @Select("select uid, username uname, password pwd, phone mob from user where username = #{username} and phone = #{phone}")
    /* @Results 映射结果集注解标签
     * id 为当前map映射的唯一标识符，可以让其他映射通过@ResultMap("idValue") 来直接引用当前已经写过的映射结果集
     * value 映射具体内容
     * */
    @Results(id = "userMapResult", value = {
            /* @Result()与.xml文件中的<result>标签编写格式相同，
             *     column：为sql查询结果的列名
             *     property: 为column列需要与之映射的类的属性名
             *     id: 用于判断当前列是否为id列，
             *         若是id列时，用id = true 进行相关的限制，
             *         若不是，可以省略不写，也可以写成 id=false
             * 注意：若返回自定义类的属性名与列名映射相同，则可以忽略不写此项映射
             *      id项映射必须写，不然会找不到值
             */
            @Result(column = "uid", property = "uid", id = true),
            @Result(column = "uname", property = "username"),
            @Result(column = "pwd", property = "password"),
            @Result(column = "mob", property = "phone")
    })
    ArrayList<User> findUsersByUsernameAndPhone(@Param("username") String username, @Param("phone") String phone);

    @Select("select uid, username, password, phone from user where uid = #{uid}")
    @Results(id = "userMapResult1", value = {
            @Result(column = "uid", property = "uid", id = true),
            @Result(property = "role", column = "uid",
                    /* @Result 注解用于配置映射关系
                     *     property: 指定返回自定义类的属性
                     *     column: 指定列作为参数传入后续的犯法中
                     * @One(一对一映射结果集) 处理两个表之间的一对一关系。
                     *     select: 指定当前映射调用方法获取最终数据
                     *     fetchType: 设置加载模式 FetchType.LAZY 懒加载, FetchType.DEFAULT 默认加载, FetchType.EAGER 侵入式加载
                     */
                    one = @One(select = "mapper.RoleAnnotationMapper.findRoleByUid", fetchType = FetchType.LAZY))
    })
    public User findUserByUid(@Param("uid") Integer uid);
}
